import React from "react";
import { createForm, Field } from "@formily/core";
import { createSchemaField, ISchema } from "@formily/react";
import {
  Form,
  FormItem,
  Space,
  Input,
  Select,
  ArrayItems,
} from "@formily/antd";
import { Modal } from "antd";
import { getOptions } from "src/utils";
import { Field as FieldProps } from "src/utils/interface";

interface Props {
  type: string;
  initData: FieldProps;
  visible: boolean;
  setVisible: (visible: boolean) => void;
  handleOK: (formData: FieldProps) => void;
}

const TreeNodeForm: React.FC<Props> = (props) => {
  const form = createForm({ initialValues: props.initData });
  const SchemaField = createSchemaField({
    components: {
      FormItem,
      Space,
      Input,
      Select,
      ArrayItems,
    },
  });

  const schema: ISchema = {
    type: "object",
    properties: {
      name: {
        type: "string",
        title: "Field Name",
        required: true,
        "x-decorator": "FormItem",
        "x-component": "Input",
      },
      description: {
        type: "string",
        title: "Description",
        "x-decorator": "FormItem",
        "x-component": "Input",
      },
      type: {
        type: "string",
        title: "Field Type",
        required: true,
        "x-decorator": "FormItem",
        "x-component": "Select",
        "x-reactions": (field: Field) => {
          // 控制 enum 的显隐
          field.form.setFieldState(field.query(".enum"), (state) => {
            state.display = field.value === "enum" ? "visible" : "none";
          });
          // 控制 itemType 的显隐
          field.form.setFieldState(field.query(".itemType"), (state) => {
            state.display = field.value === "list" ? "visible" : "none";
          });
        },
        enum: getOptions([
          "string",
          "boolean",
          "float32",
          "float64",
          "time.Time",
          "list",
          "struct",
          "enum",
          "uint8",
          "uint16",
          "uint32",
          "uint64",
          "int8",
          "int16",
          "int32",
          "int64",
        ]),
      },
      enum: {
        type: "array",
        title: "Enum",
        required: true,
        "x-decorator": "FormItem",
        "x-component": "ArrayItems",
        items: {
          type: "object",
          properties: {
            space: {
              type: "void",
              "x-component": "Space",
              properties: {
                index: {
                  type: "string",
                  title: "Index",
                  required: true,
                  "x-decorator": "FormItem",
                  "x-component": "Input",
                  "x-reactions": (field: Field) => {
                    const path = field.path.entire.toString().split(".");
                    const index = path[path.length - 2];
                    !field.value && (field.value = index);
                  },
                },
                value: {
                  type: "string",
                  title: "Value",
                  required: true,
                  "x-decorator": "FormItem",
                  "x-component": "Input",
                },
                remove: {
                  type: "void",
                  "x-decorator": "FormItem",
                  "x-component": "ArrayItems.Remove",
                },
              },
            },
          },
        },
        properties: {
          add: {
            type: "void",
            title: "Add Enum Value",
            "x-component": "ArrayItems.Addition",
          },
        },
      },
      itemType: {
        type: "string",
        title: "Field Item Type",
        required: true,
        "x-decorator": "FormItem",
        "x-component": "Select",
        enum: getOptions(["string", "boolean", "list", "struct"]),
      },
      itemType2: {
        type: "string",
        title: "Field Item Type2",
        required: true,
        "x-decorator": "FormItem",
        "x-component": "Select",
        "x-reactions": (field: Field) => {
          field.form.setFieldState(field.query(".itemType"), (state) => {
            field.display = state.value === "list" ? "visible" : "none";
          });
        },
        enum: getOptions(["string", "boolean", "struct"]),
      },
    },
  };

  return (
    <Modal
      title={props.type === "add" ? "Add Field" : "Edit Field"}
      visible={props.visible}
      onOk={() => {
        form.validate().then(() => {
          props.handleOK(form.values);
        });
      }}
      onCancel={() => props.setVisible(false)}
    >
      <Form form={form} labelCol={8} wrapperCol={14}>
        <SchemaField schema={schema} />
      </Form>
    </Modal>
  );
};

export default TreeNodeForm;
